class UserController {

  def authenticateService
  def mailNotifierService
  def mailReaderService

  def index = { redirect(action: list, params: params) }

  // the delete, save and update actions only accept POST requests
  static allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']

  def list = {
    if (!params.max) params.max = 10
    [userInstanceList: User.list(params)]
  }

  def show = {
    def userInstance = User.get(params.id)

    if (!userInstance) {
      flash.message = "User not found with id ${params.id}"
      redirect(action: list)
    }
    else { return [userInstance: userInstance] }
  }

  def delete = {
    def userInstance = User.get(params.id)
    if (userInstance && (userInstance == authenticateService.userDomain() || authenticateService.ifAllGranted(Role.ADMIN))) {
      userInstance.authorities.each {
        it.removeFromPeople(userInstance)
      }
      userInstance.delete()
      flash.message = "User ${params.id} deleted"
      redirect(action: list)
    } else {
      flash.message = "User not found with id ${params.id} or no permission to delete user"
      redirect(action: list)
    }
  }

  def edit = {
    def userInstance = User.get(params.id)
    if (!userInstance || (userInstance != authenticateService.userDomain() && !authenticateService.ifAllGranted(Role.ADMIN))) {
      flash.message = "User not found with id ${params.id} or no permission to change user"
      redirect(action: list)
    }
    else {
      return [userInstance: userInstance]
    }
  }

  def update = {
    def userInstance = User.get(params.id)
    if (userInstance && (userInstance == authenticateService.userDomain() || authenticateService.ifAllGranted(Role.ADMIN))) {
      if (params.version) {
        def version = params.version.toLong()
        if (userInstance.version > version) {

          userInstance.errors.rejectValue("version", "user.optimistic.locking.failure", "Another user has updated this User while you were editing.")
          render(view: 'edit', model: [userInstance: userInstance])
          return
        }
      }
      def oldPW = userInstance.passwd
      userInstance.properties = params
      if (params.passwd == null && params.pass == null) {
        userInstance.passwd = oldPW
        userInstance.pass = oldPW
      } else {
        userInstance.passwd = authenticateService.passwordEncoder(userInstance.passwd)
        userInstance.pass = authenticateService.passwordEncoder(userInstance.pass)
      }
      if (userInstance.validate() && !userInstance.hasErrors() && userInstance.save()) {
        flash.message = "User ${params.id} updated"
        redirect(action: show, id: userInstance.id)
      }
      else {
        render(view: 'edit', model: [userInstance: userInstance])
      }
    }
    else {
      flash.message = "User not found with id ${params.id} or no permission to change user"
      redirect(action: edit, id: params.id)
    }
  }

  def create = {
    def userInstance = new User()
    userInstance.properties = params
    return ['userInstance': userInstance]
  }

  def save = {
    def userInstance = new User(params)
    userInstance.passwd = authenticateService.passwordEncoder(userInstance.passwd)
    userInstance.pass = userInstance.passwd
    if (!userInstance.hasErrors() && userInstance.save()) {
      userInstance.profile = new Profile(firstName: '[First Name]', lastName: '[Last Name]')
      Role.findByAuthority(Role.USER).addToPeople(userInstance)
      userInstance.merge()
      flash.message = "User ${userInstance.id} created"
      redirect(action: show, id: userInstance.id)
    }
    else {
      render(view: 'create', model: [userInstance: userInstance])
    }
  }

  def sendTestMail = {
    def userInstance = User.get(params.id)
    if (userInstance && (userInstance == authenticateService.userDomain() || authenticateService.ifAllGranted(Role.ADMIN))) {
      def emailAddress = userInstance.emailAddresses.find {it.isMain == true}
      if (emailAddress) {
        mailNotifierService.sendTestMail(emailAddress.email)
        flash.message = "Test mail sent to ${emailAddress.email}"
      }else {
        flash.message = 'No main Mail Address found. Please specify one of your Mail Adresses as "main"'
      }
      redirect(action: show, id: userInstance.id)
    } else {
      flash.message = "User not found with id ${params.id} or no permission to send test mails to user."
      redirect(controller: 'profile', action: 'list')
    }
  }
  
  def toggleEvent = {
    toggleAlert('event')
  }

  def toggleDailyMailDigest = {
    toggleAlert('dailyDigest')
  }

  def toggleWeeklyMailDigest = {
    toggleAlert('weeklyDigest')
  }

  private toggleAlert = {alertType ->
    def userInstance = User.read(params.id)
    if (userInstance != null && alertType != null) {
      log.debug "Updating alertType: ${alertType} for user: ${userInstance}"
      if (alertType.equalsIgnoreCase('event')) {
        User.executeUpdate("update User u set u.eventAlert = ${!userInstance.eventAlert} where u.id = ${userInstance.id}")
        //userInstance.eventAlert = !userInstance.eventAlert
      } else if (alertType.equalsIgnoreCase('dailyDigest')) {
        User.executeUpdate("update User u set u.dailyDigest = ${!userInstance.dailyDigest} where u.id = ${userInstance.id}")
        //userInstance.dailyDigest = !userInstance.dailyDigest
      } else if (alertType.equalsIgnoreCase('weeklyDigest')) {
        User.executeUpdate("update User u set u.weeklyDigest = ${!userInstance.weeklyDigest} where u.id = ${userInstance.id}")
        //userInstance.weeklyDigest = !userInstance.weeklyDigest
      }
      /*
      if (userInstance.validate() && !userInstance.hasErrors() && userInstance.save()) {
        flash.message = "Alert successfully updated"
      } else {
        flash.message = "An error occurred while updating the alert"
      }
      */
      redirect(action: show, id: userInstance.id)
    } else {
      flash.message = "User not found with id ${params.id}"
      redirect(action: list)
    }
  }
}
